package routeRule

import (
	"errors"
	"sort"
	"strings"
)

// RouteRuleArray 路由规则解析数组
// /a/bb|cc/*/:/b/*
type RouteRuleArray [][]string

// ParseRoute
// Deprecated
func ParseRoute(rulePattern string) ([]string, error) {
	if rulePattern == "" {
		return nil, errors.New("路由规不能为空")
	}
	if rulePattern[0] != '/' {
		return nil, errors.New("路由规则必须以/开始")
	}
	if rulePattern == "/" {
		return []string{"/"}, nil
	}
	parts := strings.Split(rulePattern, "/")

	//去除头部空格
	var i = 0
	for i < len(parts) {
		if parts[i] != "" {
			break
		}
		i++
	}
	parts = append(parts[0:1], parts[i:]...)
	//去除非尾部空格的所有空格
	for i = 1; i < len(parts); i++ {
		if parts[i] == "" && i+1 != len(parts) {
			j := i
			for ; j < len(parts)-1; j++ {
				if parts[j] != "" {
					break
				}
			}
			parts = append(parts[0:i], parts[j:]...)
			continue
		} else if parts[i] == "*" && i+1 < len(parts) && (parts[i+1] == "*" || parts[i+1] == ":") {
			parts = append(parts[0:i+1], parts[i+2:]...)
			continue
		}
	}

	parts[0] = "/"
	if parts[len(parts)-1] == "" {
		parts[len(parts)-1] = "*"
	}

	return parts, nil
}

func Parse(rulePattern string) (RouteRuleArray, error) {
	if len(rulePattern) < 1 || rulePattern[0] != '/' {
		return nil, errors.New("路由规则必须以/开始")
	}
	var routeRuleArray = [][]string{{"/"}}

	for i := 1; i < len(rulePattern); i++ {
		if rulePattern[i] != '/' {
			for j := i; j < len(rulePattern); j++ {
				if rulePattern[j] == '/' {
					item := rulePattern[i:j]
					groupItem := strings.Split(item, "|")
					//group路由中不能包含空格、*、:
					for key, _ := range groupItem {
						if groupItem[key] == "" {
							groupItem = append(groupItem[:key], groupItem[key+1:]...)
						} else if key > 1 && (groupItem[key] == "*" || groupItem[key] == ":") {
							groupItem = append(groupItem[:key], groupItem[key+1:]...)
						}
					}
					//group 按字母顺序排序
					sort.Slice(groupItem, func(i, j int) bool {
						return strings.Compare(groupItem[i], groupItem[j]) < 0
					})
					if len(routeRuleArray) >= 1 && len(routeRuleArray[len(routeRuleArray)-1]) == 1 && routeRuleArray[len(routeRuleArray)-1][0] == "*" && len(groupItem) == 1 {
						if !(groupItem[0] == "*" || groupItem[0] == ":") {
							routeRuleArray = append(routeRuleArray, groupItem)
						}

					} else {
						routeRuleArray = append(routeRuleArray, groupItem)
					}

					i = j - 1
					break
				} else if j == len(rulePattern)-1 {
					item := rulePattern[i:]

					groupItem := strings.Split(item, "|")
					//group路由中不能包含空格、*、:
					for key, _ := range groupItem {
						if groupItem[key] == "" {
							groupItem = append(groupItem[:key], groupItem[key+1:]...)
						} else if key > 1 && (groupItem[key] == "*" || groupItem[key] == ":") {
							groupItem = append(groupItem[:key], groupItem[key+1:]...)
						}
					}
					//group 按字母顺序排序
					sort.Slice(groupItem, func(i, j int) bool {
						return strings.Compare(groupItem[i], groupItem[j]) < 0
					})
					if len(routeRuleArray) >= 1 && len(routeRuleArray[len(routeRuleArray)-1]) == 1 && routeRuleArray[len(routeRuleArray)-1][0] == "*" && len(groupItem) == 1 {
						if !(groupItem[0] == "*" || groupItem[0] == ":") {
							routeRuleArray = append(routeRuleArray, groupItem)
						}

					} else {
						routeRuleArray = append(routeRuleArray, groupItem)
					}
					i = j
					break
				}
			}
		} else if i == len(rulePattern)-1 {
			groupItem := []string{"*"}
			if len(routeRuleArray) >= 1 && len(routeRuleArray[len(routeRuleArray)-1]) == 1 {
				if routeRuleArray[len(routeRuleArray)-1][0] != "*" {
					routeRuleArray = append(routeRuleArray, groupItem)
				}
			} else {
				routeRuleArray = append(routeRuleArray, groupItem)
			}
		}
	}
	return routeRuleArray, nil
}

func FormatRouteRule(routeRuleArray [][]string) string {
	var builder strings.Builder
	for i := 0; i < len(routeRuleArray); i++ {
		if len(routeRuleArray[i]) == 1 {
			builder.WriteString(routeRuleArray[i][0])
			if i > 0 && i < len(routeRuleArray)-1 {
				builder.WriteString("/")
			}
		} else {
			for key, item := range routeRuleArray[i] {
				builder.WriteString(item)
				if key < len(routeRuleArray[i])-1 {
					builder.WriteString("|")
				}
			}
			if i < len(routeRuleArray)-1 {
				builder.WriteString("/")
			}
		}
	}

	return builder.String()
}
